package com.example.graalvm21.utils.security;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.security.Security;

/**
 * <p>工具类-SM4加密</p>
 *
 * @author wz
 * @date 2025/10/30 09:00
 */
public class Sm4Utils {

    private static final String ALGORITHM = "SM4/CBC/PKCS7Padding";
    private static final int KEY_IV_LENGTH = 16; // 严格16字节

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    // 生成16字节随机密钥，返回Base64字符串（用于存储）
    public static String generateKeyBase64() {
        byte[] key = new byte[KEY_IV_LENGTH];
        new SecureRandom().nextBytes(key);
        return Base64.toBase64String(key);
    }

    // 生成16字节随机IV，返回Base64字符串（用于存储）
    public static String generateIVBase64() {
        return generateKeyBase64();
    }

    // 将存储的Base64密钥字符串转为16字节数组（核心方法）
    public static byte[] keyBase64ToBytes(String keyBase64) {
        byte[] key = Base64.decode(keyBase64);
        if (key.length != KEY_IV_LENGTH) {
            throw new IllegalArgumentException("密钥必须为16字节（Base64解码后）");
        }
        return key;
    }

    // 将存储的Base64 IV字符串转为16字节数组
    public static byte[] ivBase64ToBytes(String ivBase64) {
        return keyBase64ToBytes(ivBase64); // 逻辑相同
    }

    // 加密（接收字节数组类型的key和iv）
    public static String encrypt(String content, byte[] key, byte[] iv) throws Exception {
        validateLength(key, iv);
        Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "SM4"), new IvParameterSpec(iv));
        return Base64.toBase64String(cipher.doFinal(content.getBytes(StandardCharsets.UTF_8)));
    }

    public static String encrypt(String encryptedContent, String key, String iv) throws Exception {
        return encrypt(encryptedContent, ivBase64ToBytes(key), ivBase64ToBytes(iv));
    }

    // 解密（接收字节数组类型的key和iv）
    public static String decrypt(String encryptedContent, byte[] key, byte[] iv) throws Exception {
        validateLength(key, iv);
        Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "SM4"), new IvParameterSpec(iv));
        return new String(cipher.doFinal(Base64.decode(encryptedContent)), StandardCharsets.UTF_8);
    }

    public static String decrypt(String encryptedContent, String key, String iv) throws Exception {
        return decrypt(encryptedContent, ivBase64ToBytes(key), ivBase64ToBytes(iv));
    }

    private static void validateLength(byte[] key, byte[] iv) {
        if (key.length != KEY_IV_LENGTH || iv.length != KEY_IV_LENGTH) {
            throw new IllegalArgumentException("密钥和IV必须为16字节");
        }
    }
}
